/*
 * @(#)IHEConfig.java
 * Date 2013-04-09
 * Version 1.0
 * Author Jim Horner
 * Copyright (c)2012
 */


package us.hornerscorners.lamppost.ihecommon.config;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.annotation.PostConstruct;

import javax.enterprise.context.ApplicationScoped;

import javax.enterprise.inject.Alternative;

import org.apache.commons.lang3.ArrayUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import us.hornerscorners.lamppost.config.ClientConfig;
import us.hornerscorners.lamppost.config.EndpointConfig;
import us.hornerscorners.lamppost.config.IServiceConfig;
import us.hornerscorners.lamppost.config.ModelConfig;


/**
 * Class description
 *
 *
 * @version        v1.0, 2013-04-09
 * @author         Jim Horner
 */
@ApplicationScoped
@Alternative
public class IHEConfig {

    /** Field description */
    private String assigningAuthority;

    /** Field description */
    private AtnaConfig atnaConfig;

    /** Field description */
    private ClientConfig clientConfig;

    /** Field description */
    private IDataStoreConfig dataStoreConfig;

    /** Field description */
    private String homeCommunityId;

    /** Field description */
    private boolean loaded;

    /** Field description */
    private final Logger logger = LoggerFactory.getLogger(getClass());

    /** Field description */
    private ModelConfig modelConfig;

    /** Field description */
    private List<IServiceConfig> serviceConfigs;

    /** Field description */
    private List<EndpointConfig> serviceEndpoints;

    /**
     * Constructs ...
     *
     */
    public IHEConfig() {

        super();
        this.serviceConfigs = new ArrayList<>();
        this.serviceEndpoints = new ArrayList<>();
    }

    /**
     * Method description
     *
     *
     * @param configType
     *
     * @return
     */
    public IServiceConfig findServiceConfig(IHEServiceType configType) {

        IServiceConfig result = null;
        IServiceConfig[] list = findServiceConfigs(configType);

        if (ArrayUtils.isNotEmpty(list)) {
            result = list[0];
        }

        return result;
    }

    /**
     * Method description
     *
     *
     * @param type
     *
     * @return
     */
    public IServiceConfig[] findServiceConfigs(IHEServiceType type) {

        List<IServiceConfig> result = new ArrayList<>();

        for (IServiceConfig config : this.serviceConfigs) {

            if (config.getServiceType().isSameType(type)) {

                result.add(config);
            }
        }

        return result.toArray(new IServiceConfig[result.size()]);
    }

    /**
     * Method description
     *
     *
     * @param deviceId
     *
     * @return
     */
    public EndpointConfig findServiceEndpoint(String deviceId) {

        EndpointConfig result = null;

        for (EndpointConfig config : this.serviceEndpoints) {

            if (config.getId().equals(deviceId)) {

                result = config;
            }
        }

        return result;
    }

    /**
     * Method description
     *
     *
     * @param deviceIds
     *
     * @return
     */
    public EndpointConfig[] findServiceEndpoints(Collection<String> deviceIds) {

        List<EndpointConfig> result = new ArrayList<>();

        for (EndpointConfig config : this.serviceEndpoints) {

            if (deviceIds.contains(config.getId())) {

                result.add(config);
            }
        }

        return result.toArray(new EndpointConfig[result.size()]);
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public String getAssigningAuthority() {
        return assigningAuthority;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public AtnaConfig getAtnaConfig() {
        return atnaConfig;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public ClientConfig getClientConfig() {
        return clientConfig;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public IDataStoreConfig getDataStoreConfig() {
        return dataStoreConfig;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public String getHomeCommunityId() {
        return homeCommunityId;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public ModelConfig getModelConfig() {
        return modelConfig;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public List<IServiceConfig> getServiceConfigs() {
        return serviceConfigs;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public List<EndpointConfig> getServiceEndpoints() {
        return serviceEndpoints;
    }

    /**
     * Method description
     *
     */
    @PostConstruct
    public void initialize() {

        logger.debug("IHEConfig validation (postConstruct)...");

        // validate

        IHEServiceType[] onlyOneTypes = new IHEServiceType[] { IHEServiceType.Registry,
                IHEServiceType.Repository, IHEServiceType.PDQ, IHEServiceType.PIX,
                IHEServiceType.XCA };

        for (IHEServiceType configType : onlyOneTypes) {

            IServiceConfig[] list = findServiceConfigs(configType);

            if (ArrayUtils.isNotEmpty(list) && (list.length > 1)) {

                String msg =
                    String.format(
                        "There should be only one %s stanza under serviceConfigs in the config file.",
                        configType.name());

                throw new IllegalStateException(msg);
            }
        }
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public boolean isLoaded() {
        return loaded;
    }

    /**
     * Method description
     *
     *
     * @param assigningAuthority
     */
    public void setAssigningAuthority(String assigningAuthority) {
        this.assigningAuthority = assigningAuthority;
    }

    /**
     * Method description
     *
     *
     * @param atnaConfig
     */
    public void setAtnaConfig(AtnaConfig atnaConfig) {
        this.atnaConfig = atnaConfig;
    }

    /**
     * Method description
     *
     *
     * @param clientConfig
     */
    public void setClientConfig(ClientConfig clientConfig) {
        this.clientConfig = clientConfig;
    }

    /**
     * Method description
     *
     *
     * @param dataStoreConfig
     */
    public void setDataStoreConfig(IDataStoreConfig dataStoreConfig) {
        this.dataStoreConfig = dataStoreConfig;
    }

    /**
     * Method description
     *
     *
     * @param homeCommunityId
     */
    public void setHomeCommunityId(String homeCommunityId) {
        this.homeCommunityId = homeCommunityId;
    }

    /**
     * Method description
     *
     *
     * @param loaded
     */
    public void setLoaded(boolean loaded) {
        this.loaded = loaded;
    }

    /**
     * Method description
     *
     *
     * @param modelConfig
     */
    public void setModelConfig(ModelConfig modelConfig) {
        this.modelConfig = modelConfig;
    }

    /**
     * Method description
     *
     *
     * @param serviceConfigs
     */
    public void setServiceConfigs(List<IServiceConfig> serviceConfigs) {
        this.serviceConfigs = serviceConfigs;
    }

    /**
     * Method description
     *
     *
     * @param serviceEndpoints
     */
    public void setServiceEndpoints(List<EndpointConfig> serviceEndpoints) {
        this.serviceEndpoints = serviceEndpoints;
    }
}
